package controller

import (
	"KD_web/go/dao"
	"KD_web/go/entity"
	"KD_web/go/errors"
	"KD_web/go/service"
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"
)

func Login(c *gin.Context) {
	var req entity.LoginRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"err": errors.ErrJsonAnalyze})
		return
	}

	user, err := service.LoginUser(&req)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()})
	}
	if user != nil {
		c.JSON(http.StatusOK, gin.H{
			"code":     200,
			"id":       user.Id,
			"username": user.Name,
			"email":    user.Email,
			"role":     user.Role,
			"msg":      "success",
		})
	}
}

// add new user
func CreateUser(c *gin.Context) {
	var user entity.User
	if err := c.BindJSON(&user); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"code": 4004, "msg": "Invalid input!"})
		return
	}

	err := service.CreateUser(&user)
	if err != nil {
		if customErr, ok := err.(*errors.CustomError); ok {
			c.JSON(HttpStatusForErrorCode(customErr.Code), customErr)
		} else {
			c.JSON(http.StatusInternalServerError, gin.H{"code": 1000, "msg": "Unknown error"})
		}
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "success",
		"data": user,
	})

}

// get user list
func GetUserList(c *gin.Context) {
	todolist, err := service.GetAllUser()
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()})
	} else {
		c.JSON(http.StatusOK, gin.H{
			"code": 200,
			"msg":  "success",
			"data": todolist,
		})
	}
}

// get user by id
func GetUserById(c *gin.Context) {
	// get id from url
	id := c.Param("id")
	user, err := service.GetUserById(id)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()})
	} else {
		c.JSON(http.StatusOK, gin.H{
			"code":       200,
			"msg":        "success",
			"Name":       user.Name,
			"Avatar":     user.Avatar,
			"Email":      user.Email,
			"CreateTime": user.CreateTime,
			"UpdateTime": user.UpdateTime,
		})
	}
}

// delete user by id
func DeleteUser(c *gin.Context) {
	// get id from url
	id := c.Param("id")
	err := service.DeleteUserById(id)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()})
	} else {
		c.JSON(http.StatusOK, gin.H{
			"code": 200,
			"msg":  "success",
		})
	}
}

// update user information
func UpdateUser(c *gin.Context) {
	var user entity.User
	user.Id, _ = strconv.Atoi(c.Param("id"))

	if err := c.BindJSON(&user); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"errors": err.Error()})
	}

	err := service.UpdateUser(&user)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"errors": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "User information updated successfully",
		"user": user,
	})
}

// update user's Role
func UpdateUserRole(c *gin.Context) {
	userId, err := strconv.Atoi(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"})
		return
	}
	// 定义请求体格式
	var requestBody struct {
		Role int `json:"Role"`
	}
	// 绑定请求
	if err := c.BindJSON(&requestBody); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
		return
	}
	if err := service.ChangeRole(userId, requestBody.Role); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "User role changed successfully",
	})
}

// upload Avatar
func UploadAvatar(c *gin.Context) {
	file, err := c.FormFile("file")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	// 上传文件
	uploadPath := "D:/Projects/Go_Projects/KD_web/resources/avatars"
	uniqueFileName := filepath.Join(uploadPath, file.Filename)
	fileName := filepath.Base(uniqueFileName)
	if err := c.SaveUploadedFile(file, uniqueFileName); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	// 获取用户
	userId, err := strconv.Atoi(strings.Split(fileName, ".")[0])
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"})
		return
	}
	var user entity.User
	if err := dao.SqlSession.First(&user, userId).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
		return
	}

	// 删除旧头像，如果旧头像名称不为 defaultAvatar.jpg
	if user.Avatar != "" && user.Avatar != "defaultAvatar.jpg" {
		oldAvatarPath := filepath.Join(uploadPath, user.Avatar)
		if err := os.Remove(oldAvatarPath); err != nil {
			// 这里可以记录日志，但不需要返回错误
			fmt.Printf("Failed to remove old avatar: %s\n", err)
		}
	}
	// 更新用户信息
	user.Avatar = fileName
	user.Password = ""
	if err := service.UpdateUser(&user); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code":      200,
		"msg":       "User information updated successfully",
		"message":   "文件上传成功",
		"file_path": uniqueFileName,
	})
}

func HttpStatusForErrorCode(code int) int {
	switch code {
	case 5001:
		return http.StatusConflict // 用户已存在
	case 5002:
		return http.StatusNotFound // 用户未找到
	case 5003:
		return http.StatusGatewayTimeout // json解析失败
	case 5004:
		return http.StatusBadRequest // 错误密码
	case 5005:
		return http.StatusBadRequest // 错误邮箱
	case 5006:
		return http.StatusNotFound //图表查询失败
	case 5007:
		return http.StatusGatewayTimeout // json格式错误
	case 5008:
		return http.StatusBadRequest // 查询表格失败
	case 5009:
		return http.StatusConflict // 分析结论已存在
	case 4001:
		return http.StatusBadRequest // 密码格式错误
	case 4002:
		return http.StatusBadRequest // 邮箱或名字格式错误
	case 4003:
		return http.StatusForbidden // 权限错误
	case 4004:
		return http.StatusInternalServerError // 创建用户失败
	case 4005:
		return http.StatusBadRequest // 无效输入
	default:
		return http.StatusInternalServerError // 未知错误
	}
}
